﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using devtm.Aop.Behavior;
using devtm.Aop.Event;
using System.Diagnostics;
using System.Reflection;


namespace devtm.Aop.InternalProcess.Cache
{

    public class CacheStrategy : ICacheStrategy
    {       


        public virtual bool GetKey(Event.InterceptEventArgs args, out uint key)
        {


            if ((args.Member as MethodInfo).ReturnType.Name == "Void")
                throw new InjectionException(new Exception(string.Format("cache on method {0} failed, because void type can't be cached", args.Member.ToString())));

            key = 0;

            if (ResolveStrategyCacheFor(args))
            {
                key = GetUniqueKey(args);
                return true;
            }

            return false;

        }

       

        public void InitializeCacheItem(ref CacheItem item, Event.InterceptEventArgs args)
        {

            var second = 0;
            bool sliding = false;

            // Lecture des parametres
            if (args.Properties.Contains("Time"))
                second = (int)args.Properties.Get("Time");

            if (args.Properties.Contains("Sliding"))
                sliding = (bool)args.Properties.Get("Sliding");

            // set
            item.Time.Interval = CacheTimer.GetTimeSpan(second);
            item.Time.Sliding = sliding;

        }

        


        #region Compute Key

        [DebuggerStepThrough]
        protected virtual uint GetUniqueKey(Event.InterceptEventArgs args)
        {
            string fullMethodName = args.Member.DeclaringType.FullName + args.Member.Name;
            StringBuilder s = new StringBuilder(fullMethodName);
            string k = s.SerializeParameters(args);
            uint retour = Crc32.Calculate(k);
            return retour;
        }


       

        #endregion


        public virtual bool ResolveStrategyCacheFor(Event.InterceptEventArgs args)
        {

            if (args.Properties.Contains("Behevior"))
            {
                
                BehaviorEnum t = (BehaviorEnum)args.Properties.Get("Behevior");
                
                if (t == BehaviorEnum.Ignore)
                    return false;

            }

            return true;

        }


    }
}
